﻿using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Controls;
using Trinity.Components.Combat.Resources;
using Trinity.Framework;
using Trinity.Framework.Actors.ActorTypes;
using Trinity.Framework.Helpers;
using Trinity.Framework.Objects;
using Trinity.Framework.Reference;
using Trinity.UI;
using Zeta.Common;
using Zeta.Game.Internals.Actors;


namespace Trinity.Routines.Crusader
{
  public sealed class CrusaderRolandShieldBash : CrusaderBase, IRoutine
  {
    #region Definition

    public string DisplayName => "罗兰的炖鸡";
    public string Description => "欢迎各路大神来QQ群469549087指导反馈";
    public string Author => "不正常人类研究所-殉道者";
    public string Version => "20170407";
    public string Url => "http://www.demonbuddy.cn/thread-11775-1-1.html";

    public Build BuildRequirements => new Build
    {
      Sets = new Dictionary<Set, SetBonus>
            {
                { Sets.RolandsLegacy, SetBonus.Third }
            },

      Skills = new Dictionary<Skill, Rune>
            {
                { Skills.Crusader.ShieldBash, null },
        { Skills.Crusader.ShieldGlare, null }
            },

      Items = new List<Item>
            {
                Legendary.FlailOfTheAscended,
                Legendary.DrakonsLesson,
            },
    };

    #endregion

        public TrinityPower GetOffensivePower()
    {
      TrinityActor target;
      if (Core.Buffs.HasCastingShrine)
      {
        if (Skills.Crusader.ShieldGlare.TimeSinceUse > 3000)
        {
          if (ShouldShieldGlare(out target)) 
		  {
            return ShieldGlare(target);
          }
        }
      }

      if (Core.Player.PrimaryResourcePct < 0.3f)
      {
        if (Skills.Crusader.ShieldGlare.CanCast() && TargetUtil.AnyMobsInRange(30f))
        {
          target = TargetUtil.GetBestClusterUnit() ?? CurrentTarget;
          return ShieldGlare(target);
        }
      }

      if (ShouldShieldBash(out target))
      {
        return ShieldBash(target);
      }

      List<TrinityActor> farEnemies = TargetUtil.MobsBetweenRange(30f, 80f);
      if (farEnemies.Count() != 0 && Skills.Crusader.ShieldBash.TimeSinceUse > 1500) 
	  {
        TrinityActor enemy = farEnemies.FirstOrDefault();
        if (Skills.Crusader.ShieldBash.CanCast())
        {
          return new TrinityPower(Skills.Crusader.ShieldBash.SNOPower, enemy.Distance, enemy.AcdId);
        }
      }
      return DefaultPower;
    }

    public TrinityPower GetDefensivePower()
    {
      return null;
      //return GetBuffPower();
    }

    public TrinityPower GetBuffPower()
    {
      // TrinityPower power;
    //  if (IsSteedCharging)
    //    return null;

      if (AllowedToUse(Settings.Akarats, Skills.Crusader.AkaratsChampion) && ShouldAkaratsChampion())
        return AkaratsChampion();

      if (ShouldProvoke())
        return Provoke();

      if (ShouldIronSkin())
        return IronSkin();

      if (ShouldLawsOfJustice())
        return LawsOfJustice();


      return null;
    }

    public TrinityPower GetDestructiblePower()
    {
      return DefaultPower;
    }

    public TrinityPower GetMovementPower(Vector3 destination)
    {
		if (ShouldSteedCharge())
          return SteedCharge();	
	
      return Walk(destination);
    }


    #region Settings

    public override int ClusterSize => Settings.ClusterSize;
    public override float EmergencyHealthPct => Settings.EmergencyHealthPct;

    IDynamicSetting IRoutine.RoutineSettings => Settings;
    public CrusaderSeekerOfTheLightSettings Settings { get; } = new CrusaderSeekerOfTheLightSettings();

    public sealed class CrusaderSeekerOfTheLightSettings : NotifyBase, IDynamicSetting
    {
      private SkillSettings _akarats;
      private int _clusterSize;
      private float _emergencyHealthPct;

      [DefaultValue(10)]
      public int ClusterSize
      {
        get { return _clusterSize; }
        set { SetField(ref _clusterSize, value); }
      }

      [DefaultValue(0.4f)]
      public float EmergencyHealthPct
      {
        get { return _emergencyHealthPct; }
        set { SetField(ref _emergencyHealthPct, value); }
      }

      public SkillSettings Akarats
      {
        get { return _akarats; }
        set { SetField(ref _akarats, value); }
      }

      #region Skill Defaults

      private static readonly SkillSettings AkaratsDefaults = new SkillSettings
      {
        UseMode = UseTime.Selective,
        Reasons = UseReasons.Elites | UseReasons.HealthEmergency,
      };

      #endregion

      public override void LoadDefaults()
      {
        base.LoadDefaults();
        Akarats = AkaratsDefaults.Clone();
      }

      #region IDynamicSetting

      public string GetName() => GetType().Name;
      public UserControl GetControl() => UILoader.LoadXamlByFileName<UserControl>(GetName() + ".xaml");
      public object GetDataContext() => this;
      public string GetCode() => JsonSerializer.Serialize(this);
      public void ApplyCode(string code) => JsonSerializer.Deserialize(code, this, true);
      public void Reset() => LoadDefaults();
      public void Save() { }

      #endregion
    }

    #endregion
  }
}